package com.ds.infrastructure.hyperspace.container.internal.http2;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http2.*;

import static com.ds.infrastructure.hyperspace.container.internal.http2.HyperspaceHttp2FrameTypeEnum.*;

/**
 * @author  Weishaoying
 */
public class HyperspaceHttp2FrameReadListener implements Http2FrameListener {

    @Override
    public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data,
            int padding, boolean endOfStream) throws Http2Exception {
        ctx.fireChannelRead(new HyperspaceHttp2FrameWrapper(DATA, streamId, endOfStream,
                new DefaultHttp2DataFrame(data, endOfStream, padding).retain()));
        return 0;
    }

    @Override
    public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers,
            int padding, boolean endOfStream) throws Http2Exception {
        ctx.fireChannelRead(new HyperspaceHttp2FrameWrapper(HEADERS, streamId, endOfStream,
                new DefaultHttp2HeadersFrame(headers, endOfStream, padding)));
    }

    @Override
    public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers,
            int streamDependency, short weight, boolean exclusive,
            int padding, boolean endOfStream) throws Http2Exception {
        ctx.fireChannelRead(new HyperspaceHttp2FrameWrapper(HEADERS, streamId, endOfStream,
                new HyperspaceHttp2FlowControllerState(streamDependency, weight, exclusive),
                new DefaultHttp2HeadersFrame(headers, endOfStream, padding)));
    }

    @Override
    public void onPriorityRead(ChannelHandlerContext ctx, int streamId, int streamDependency,
            short weight, boolean exclusive) throws Http2Exception {
        ctx.fireChannelRead(new HyperspaceHttp2FrameWrapper(PRIORITY, streamId,
                new HyperspaceHttp2FlowControllerState(streamDependency, weight, exclusive),
                new HyperspaceHttp2PriorityFrame(streamDependency, weight, exclusive)));
    }

    @Override
    public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode) throws Http2Exception {
        ctx.fireChannelRead(new HyperspaceHttp2FrameWrapper(RST_STREAM, streamId, true,
                new DefaultHttp2ResetFrame(errorCode)));
    }

    @Override
    public void onSettingsAckRead(ChannelHandlerContext ctx) throws Http2Exception {
        ctx.fireChannelRead(new HyperspaceHttp2FrameWrapper(SETTINGS_ACK,
                new HyperspaceHttp2SettingAckFrame()));
    }

    @Override
    public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings) throws Http2Exception {
        ctx.fireChannelRead(new HyperspaceHttp2FrameWrapper(SETTINGS,
                new DefaultHttp2SettingsFrame(settings)));
    }

    @Override
    public void onPingRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
        ctx.fireChannelRead(new HyperspaceHttp2FrameWrapper(PING,
                new DefaultHttp2PingFrame(data)));
    }

    @Override
    public void onPingAckRead(ChannelHandlerContext ctx, long data) throws Http2Exception {
        ctx.fireChannelRead(new HyperspaceHttp2FrameWrapper(PING_ACK,
                new DefaultHttp2PingFrame(data)));
    }

    @Override
    public void onPushPromiseRead(ChannelHandlerContext ctx, int streamId,
            int promisedStreamId, Http2Headers headers, int padding) throws Http2Exception {
        ctx.fireChannelRead(new HyperspaceHttp2FrameWrapper(PUSH_PROMISE, streamId,
                new HyperspaceHttp2PushPromiseFrame(promisedStreamId, headers, padding)));
    }

    @Override
    public void onGoAwayRead(ChannelHandlerContext ctx, int lastStreamId, long errorCode, ByteBuf debugData) throws Http2Exception {
        ctx.fireChannelRead(new HyperspaceHttp2FrameWrapper(GO_AWAY,
                new HyperspaceHttp2GoAwayFrame(lastStreamId,
                        new DefaultHttp2GoAwayFrame(errorCode, debugData).retain())));
    }

    @Override
    public void onWindowUpdateRead(ChannelHandlerContext ctx, int streamId, int windowSizeIncrement) throws Http2Exception {
        ctx.fireChannelRead(new HyperspaceHttp2FrameWrapper(WINDOW_UPDATE, streamId,
                new DefaultHttp2WindowUpdateFrame(windowSizeIncrement)));
    }

    @Override
    public void onUnknownFrame(ChannelHandlerContext ctx, byte frameType, int streamId, Http2Flags flags, ByteBuf payload) throws Http2Exception {
        ctx.fireChannelRead(new HyperspaceHttp2FrameWrapper(UNKNOWN, streamId,
                new DefaultHttp2UnknownFrame(frameType, flags, payload).retain()));

    }
}
